home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / xlib / pcx2csrc / pcx.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-09  |  3.6 KB  |  147 lines

  1. // Some routines for loading PCX files
  2.  
  3. #include        <stdio.h>
  4. #include        <dos.h>
  5. #include        <io.h>
  6. #include        <fcntl.h>
  7. #include        <mem.h>
  8.  
  9. #include "pcx.h"
  10.  
  11. const long IMAGE_SIZE=64000; // Size of PCX bitmap
  12.  
  13. int Pcx::load(char far *filename,pcx_struct *pcx)
  14. {
  15.  
  16. // Function to load PCX data from file FILENAME into
  17. //  structure PCX.
  18.  
  19.     // Open file; return nonzero value on error
  20.  
  21.     if ((infile=open(filename,O_BINARY))==NULL)
  22.             return(-1);
  23.  
  24.   // Move file pointer to start of header:
  25.  
  26.     lseek(infile,0L,SEEK_SET);
  27.  
  28.   // Reader header from PCX file:
  29.  
  30.     int readlen=read(infile,&(pcx->header),
  31.                                         sizeof(pcx_header));
  32.  
  33.   // Decompress bitmap and place in buffer,
  34.   //  returning non-zero value if error occurs:
  35.  
  36.     if (!load_image(infile,pcx)) return(-1);
  37.  
  38.   // Decompress palette and store in array:
  39.  
  40.     load_palette(infile,pcx);
  41.  
  42.     close(infile); // Close PCX file
  43.     return(0);     // Return non-error condition
  44. }
  45.  
  46. int Pcx::load_image(int pcxfile,pcx_struct *pcx)
  47.  
  48. // Decompress bitmap and store in buffer
  49.  
  50. {
  51.   // Symbolic constants for encoding modes, with
  52.   //  BYTEMODE representing uncompressed byte mode
  53.   //  and RUNMODE representing run-length encoding mode:
  54.  
  55.   const int BYTEMODE=0, RUNMODE=1;
  56.  
  57.   // Buffer for data read from disk:
  58.  
  59.   const int BUFLEN=5*1024;
  60.     int mode=BYTEMODE;  // Current encoding mode being used,
  61.               //  initially set to BYTEMODE
  62.   int readlen;  // Number of characters read from file
  63.     static unsigned char outbyte; // Next byte for buffer
  64.   static unsigned char bytecount; // Counter for runs
  65.     static unsigned char buffer[BUFLEN]; // Disk read buffer
  66.  
  67.   // Allocate memory for bitmap buffer and return -1 if
  68.   //  an error occurs:
  69.  
  70.     if ((pcx->image=new unsigned char[IMAGE_SIZE])==NULL)
  71.         return(-1);
  72.     int bufptr=0; // Point to start of buffer
  73.     readlen=0;    // Zero characters read so far
  74.  
  75.   // Create pointer to start of image:
  76.  
  77.     unsigned char *image_ptr=pcx->image;
  78.  
  79.   // Loop for entire length of bitmap buffer:
  80.  
  81.     for (long i=0; i<IMAGE_SIZE; i++) {
  82.         if (mode==BYTEMODE) { // If we're in individual byte
  83.               //  mode....
  84.             if (bufptr>=readlen) { // If past end of buffer...
  85.                 bufptr=0;            // Point to start
  86.  
  87.     // Read more bytes from file into buffer;
  88.     //  if no more bytes left, break out of loop
  89.  
  90.                 if ((readlen=read(pcxfile,buffer,BUFLEN))==0)
  91.                     break;
  92.             }
  93.             outbyte=buffer[bufptr++]; // Next byte of bitmap
  94.             if (outbyte>0xbf) {       // If run-length flag...
  95.  
  96.     // Calculate number of bytes in run:
  97.  
  98.                 bytecount = (int)((int)outbyte & 0x3f);
  99.                 if (bufptr>=readlen) {  // If past end of buffer
  100.                     bufptr=0;             // Point to start
  101.  
  102.       // Read more bytes from file into buffer;
  103.       //  if no more bytes left, break out of loop
  104.  
  105.                     if ((readlen=read(pcxfile,buffer,BUFLEN))==0)
  106.                         break;
  107.                 }
  108.                 outbyte=buffer[bufptr++]; // Next byte of bitmap
  109.  
  110.     // Switch to run-length mode:
  111.  
  112.                 if (--bytecount > 0) mode = RUNMODE;
  113.             }
  114.         }
  115.  
  116.     // Switch to individual byte mode:
  117.  
  118.         else if (--bytecount == 0) mode=BYTEMODE;
  119.  
  120.     // Add next byte to bitmap buffer:
  121.  
  122.         *image_ptr++=outbyte;
  123.     }
  124. }
  125.  
  126. void Pcx::load_palette(int pcxfile,pcx_struct *pcx)
  127.  
  128. // Load color register values from file into palette array
  129.  
  130. {
  131.  
  132.   // Seek to start of palette, which is always 768 bytes
  133.   //  from end of file:
  134.  
  135.     lseek(pcxfile,-768L,SEEK_END);
  136.  
  137.   // Read all 768 bytes of palette into array:
  138.  
  139.     read(pcxfile,pcx->palette,3*256);
  140.  
  141.   // Adjust for required bit shift:
  142.  
  143.     for (int i=0; i<256; i++)
  144.         for (int j=0; j<3; j++)
  145.             pcx->palette[i*3+j]=pcx->palette[i*3+j]>>2;
  146. }
  147.